package com.quanyan.ic.vendingMachine.http.interceptor;

import com.alibaba.fastjson.JSON;
import com.quanyan.ic.common.spring.SpringUtil;
import com.quanyan.ic.vendingMachine.protocol.Cmd;
import com.quanyan.ic.vendingMachine.protocol.codec.protobuf.VmMessageBuilder;
import com.quanyan.ic.vendingMachine.protocol.codec.protobuf.VmMessageProto;
import com.quanyan.ic.vendingMachine.protocol.server.session.Session;
import com.quanyan.ic.vendingMachine.protocol.server.session.SessionManager;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 * Created by zhuo.shi on 2017/8/1.
 * 当关联商品或者清空货道时，拦截操作，发送更新货道商品列表通知给客户端
 */
@Aspect
@Component
public class UpdateGridGoodsInterceptor {

    private static Logger logger = LoggerFactory.getLogger(UpdateGridGoodsInterceptor.class);

    @Pointcut("execution(* com.quanyan.ic.vendingMachine.http.service.VmAdminService.*GridGoodsMapping(..))")
    public void updateGridGoodsService() {
    }

    @Around(value = "updateGridGoodsService()")
    public Object sendGridGoodsUpdatedNotify(ProceedingJoinPoint poj) throws Throwable {
        try {
            Object result = poj.proceed();
            Object[] args = poj.getArgs();
            for (Object arg : args) {
                logger.debug("arg: {}", JSON.toJSONString(arg));
            }
            String vmNumber = String.valueOf(args[0]);
            if (StringUtils.isEmpty(vmNumber)) {
                return result;
            }
            logger.info("---> method [{}] is called, vmNumber=[{}], notify the client to update grid goods list", poj.getSignature().getName(), vmNumber);
            sendUpdateGridGoodListCmd(vmNumber);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 发送商品列表更新命令给客户端
     *
     * @param vmNumber 售货机编号
     */
    private void sendUpdateGridGoodListCmd(final String vmNumber) {
        SessionManager sessionManager = SpringUtil.getBean("sessionManager", SessionManager.class);
        Session session = sessionManager.get(vmNumber);
        if (session == null || session.getChannel() == null) {
            logger.warn("---> send cmd [{}] to vm [{}], client offline", Cmd.UPDATE_GOODSLIST_REQ.getDesc(), vmNumber);
            return;
        }
        Channel channel = session.getChannel();
        final VmMessageProto.VmMessage vmMessage = new VmMessageBuilder(vmNumber)
                .buildCmd(Cmd.UPDATE_GOODSLIST_REQ)
                .getMessage();
        ChannelFuture f = channel.writeAndFlush(
                vmMessage
        );
        f.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                logger.info("---> send cmd [{}] to vm [{}] completed, d={} c={} s={}， msg=\n{}",
                        Cmd.UPDATE_GOODSLIST_REQ.getDesc(), vmNumber, channelFuture.isDone(), channelFuture.isCancelled(), channelFuture.isSuccess(), vmMessage);
            }
        });
    }
}
